package com.gzy.rpsm_property.controller;

import com.github.pagehelper.Page;
import com.gzy.rpsm_property.pojo.Amount;
import com.gzy.rpsm_property.pojo.PageResult;
import com.gzy.rpsm_property.pojo.ResponsePojo;
import com.gzy.rpsm_property.pojo.User;
import com.gzy.rpsm_property.service.UserService;

import com.gzy.rpsm_property.utils.ValidGender;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
@Api(tags = "业主相关 API")
public class UserController {
    @Autowired
    UserService userService;
    @PostMapping("/insert")
    @ApiOperation(value = "新增业主信息，默认为未激活的状态，采用默认密码,生成随机账号。roomid通过级联菜单获得",
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "idcard", type = "String", required = true),
            @ApiImplicitParam(name = "age", type = "Integer", required = true),
            @ApiImplicitParam(name = "gender", type = "Integer", required = true),
            @ApiImplicitParam(name = "username", type = "String", required = true),
            @ApiImplicitParam(name = "user_roomid", type = "Integer", required = true),
    })
    public ResponsePojo<Integer> insertUser(@ApiIgnore User user) {
        // 需验证roomid是否存在。目前省略掉该步骤，可以拓展完成
        user.setPassword("123456");
        user.setUser_type((short) 3);
        user.setUser_status((short) 33);
        // 根据用户名的MD5值和时间戳生成用户账号。可能有极小概率重复。
        String name = DigestUtils.md5DigestAsHex(user.getUsername().getBytes(StandardCharsets.UTF_8)).substring(13, 20);
        name = name.concat(System.currentTimeMillis() % 10000 + "");
        user.setAccount(name);
        Integer result = null;
        try {
            result = userService.insertUser(user);
            return ResponsePojo.success(result);
        } catch (DuplicateKeyException e) {
            e.printStackTrace();
            return ResponsePojo.fail(result, "用户名重复");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponsePojo.fail(result, "未知异常，请联系管理员");
        }
    }










    @GetMapping("/me")
    @ApiOperation( value="获取当前登录用户信息")
    public ResponsePojo<User> me(HttpServletRequest request){
        Integer userId = (Integer) request.getAttribute("userId");
        User u = userService.queryById(userId);
        return ResponsePojo.success(u) ;
    }
    @GetMapping("/pageOfOwners")
    @ApiOperation(value="分页的业主信息。默认为第一页，每页默认10条数据。",
            notes = "若当前页小于1，强制为1；若每页行数小于1，强制为1")
    @ApiImplicitParams({
            @ApiImplicitParam(name="current",defaultValue = "1"),
            @ApiImplicitParam(name="size",defaultValue = "10")
    })
    public ResponsePojo<PageResult<User>> pageOfOwners(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        PageResult<User> page =
                userService.pageOfOwner(current, size);
        return ResponsePojo.success(page);
    }
    @GetMapping("/id/{userid}")
    @ApiOperation( value="根据用户 id 查询用户详细信息", notes="<span style='color:red'>若查询失败，返回 null</span>", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name="userid",type = "Integer",required = true)
    })
    public ResponsePojo<User> queryById(@PathVariable("userid") Integer id){
        User u = userService.queryById(id);
//        int a =1/0;//抛出异常
        if(Optional.ofNullable(u).isPresent()){
            return ResponsePojo.success(u) ;
        }
        return ResponsePojo.fail(u,"该 id 不存在对应用户");
    }



    @PutMapping("/updateStatus/{userid}")
    @ApiOperation(value = "修改用户信息", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userid", type = "Integer", required = true, paramType = "path"),
            @ApiImplicitParam(name = "account", type = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", type = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "idcard", type = "String", required = true, paramType = "query", allowableValues = "range[11,11]"),
            @ApiImplicitParam(name = "username", type = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "gender", type = "Integer", required = true, paramType = "query", allowableValues = "1,2"),
            @ApiImplicitParam(name = "age", type = "Integer", required = true, paramType = "query", value = "年龄范围：1-100")
    })
    public ResponsePojo<Integer> changeUserStatus(
            @PathVariable Integer userid,
            @RequestParam String account,
            @RequestParam String password,
            @RequestParam @Size(min = 11, max = 11) String idcard,
            @RequestParam String username,
            @RequestParam @ValidGender Integer gender,
            @RequestParam @Min(value = 1) @Max(value = 100) Integer age) {

        User user = new User();
        user.setUserid(userid);
        user.setAccount(account);
        user.setPassword(password);
        user.setIdcard(idcard);
        user.setUsername(username);
        // 将 Integer 类型的 gender 转换为 Short 类型
        user.setGender(gender.shortValue());
        user.setAge(age.shortValue());

        Set<ConstraintViolation<User>> violations = validator.validate(user);
        if (!violations.isEmpty()) {
            List<String> errors = violations.stream()
                    .map(ConstraintViolation::getMessage)
                    .collect(Collectors.toList());
            return ResponsePojo.fail(null, errors.toString());
        }

        int result = userService.changeUser(user);
        if (result == 0) {
            return ResponsePojo.fail(result, "该用户 ID 无效");
        }
        return ResponsePojo.fail(result, "用户信息更新成功");
    }

    @Autowired
    private Validator validator;


    @GetMapping("/unpaid-amount-list")
    @ApiOperation(value = "查询未缴费信息", responseContainer = "List")
    public ResponsePojo<Page<Amount>> unpaidAmountList(
            @RequestParam Integer roomId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        Page<Amount> result = userService.getUnpaidAmountsByRoomId(roomId, page, size);
        return ResponsePojo.success(result);
    }





    @ApiOperation(value = "根据账号和密码进行登录操作,只需账号和密码。回个人信息和token字符串",
            notes = "<span style='color:red'>模拟操作，密码为明文密码</span>",
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", type = "String", required = true),
            @ApiImplicitParam(name = "password", type = "String", required = true)
    })
    @PostMapping("/login")
    public ResponsePojo<User> login(
            @RequestParam("account") String account,
            @RequestParam("password") String password) {
        User result = userService.login(account, password);
        if (Optional.ofNullable(result).isPresent()) {
            return ResponsePojo.success(result);
        } else {
            return ResponsePojo.fail(null, "验证失败");
        }

    }


    @PutMapping("/activate/{userid}")
    @ApiOperation(value = "激活用户为业主", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userid", type = "Integer", required = true, paramType = "path", value = "用户ID")
    })
    public ResponseEntity<ResponsePojo<Integer>> activateUser(@PathVariable @ApiParam("用户ID") int userid) {
        int result = userService.activateUser(userid);
        if (result > 0) {
            return new ResponseEntity<>(ResponsePojo.success(result), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(ResponsePojo.fail(null, "用户激活失败"), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

}

